package com.jzo2o.market.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.market.dto.request.CouponUseReqDTO;
import com.jzo2o.api.market.dto.response.CouponUseResDTO;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.mapper.CouponWriteOffMapper;
import com.jzo2o.market.model.domain.Coupon;
import com.jzo2o.market.model.domain.CouponWriteOff;
import com.jzo2o.market.service.ICouponService;
import com.jzo2o.market.service.ICouponWriteOffService;
import com.jzo2o.mvc.utils.UserContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * <p>
 * 优惠券核销表 服务实现类
 * </p>
 * @author itcast
 * @since 2023-09-22
 */
@Service
public class CouponWriteOffServiceImpl extends ServiceImpl<CouponWriteOffMapper, CouponWriteOff> implements ICouponWriteOffService {
    @Resource
    private ICouponService couponService;

    @Override
    @Transactional
    public CouponUseResDTO use(CouponUseReqDTO couponUseReqDTO) {
        Long couponId = couponUseReqDTO.getId();
        BigDecimal totalAmount = couponUseReqDTO.getTotalAmount();
        Long userId = UserContext.currentUserId();
        LocalDateTime nowTime = LocalDateTime.now();

        Coupon coupon = couponService.getById(couponId);
        if (ObjectUtils.isEmpty(coupon) || ObjectUtils.notEqual(coupon.getUserId(), userId)) {
            throw new BadRequestException("优惠卷不存在");
        } else if (coupon.getStatus() != CouponStatusEnum.NO_USE
                || coupon.getValidityTime().isBefore(nowTime)) {
            throw new BadRequestException("优惠卷已使用/已失效");
        } else if (coupon.getAmountCondition().compareTo(totalAmount) > 0) {
            throw new BadRequestException("订单金额未达到满减金额");
        }

        Long ordersId = couponUseReqDTO.getOrdersId();
        if (!couponService.lambdaUpdate()
                .eq(Coupon::getId, couponId)
                .set(Coupon::getUseTime, nowTime)
                .set(Coupon::getStatus, CouponStatusEnum.USED)
                .set(Coupon::getOrdersId, ordersId)
                .update()) {
            throw new DBException("更新优惠卷表失败");
        }

        if (!this.save(CouponWriteOff.builder()
                .couponId(couponId)
                .userId(userId)
                .ordersId(ordersId)
                .activityId(coupon.getActivityId())
                .writeOffTime(nowTime)
                .writeOffManName(coupon.getUserName())
                .writeOffManPhone(coupon.getUserPhone())
                .build())) {
            throw new DBException("更新核销表失败");
        }

        return new CouponUseResDTO(couponService.calcDiscountAmount(coupon, totalAmount));
    }
}